﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PagedList;
using MvcAtletIS.Models;

namespace MvcAtletIS.Controllers
{
    public class LiveController : Controller
    {
        private atletisEntities db = new atletisEntities();
        
        // GET: /Live/16
        public ActionResult Index(int CompetitionId, int? DisciplineId, int? CheckPointId, int? Page, string Code)
        {
            DateTime now = DateTime.Now.Date;

            LiveModel model = new LiveModel();

            model.ActiveCompetition = db.Competitions.FirstOrDefault(c => c.ID == CompetitionId);

            // Init with Results or Start list
            if (string.IsNullOrEmpty(Code))
            {
                if (model.ActiveCompetition != null && model.ActiveCompetition.DateTo.HasValue && model.ActiveCompetition.DateFrom.Value.Date <= now)
                {
                    Code = "RES";
                }
                else
                {
                    Code = "SL";
                }
            }

            // Show Live chip data?
            if (model.ActiveCompetition != null &&
                model.ActiveCompetition.DateFrom.HasValue && model.ActiveCompetition.DateTo.HasValue &&
                model.ActiveCompetition.DateFrom.Value >= now && model.ActiveCompetition.DateTo <= now)
            {
                model.ShowLiveChipData = true;
            }

            model.DisciplineList = db.DisciplineList
                .Where(dl => dl.CompetitionId == CompetitionId && dl.Active == true)
                .OrderBy(dl => dl.ExternalId)
                .ToList();

            if (model.DisciplineList != null && model.DisciplineList.Count > 0)
            {
                if (DisciplineId == null)
                {
                    model.ActiveDiscipline = model.DisciplineList[0];
                    DisciplineId = model.DisciplineList[0].ID;
                }
                else
                {
                    model.ActiveDiscipline = db.DisciplineList.Single(dl => dl.ID == DisciplineId);
                }

                model.Code = Code;

                int pageSize = 8;
                int pageNumber = (Page ?? 1);
                List<Performances> performances = new List<Performances>();

                if (Code == "CHRES" | Code == "CHV")
                {
                    // Get CheckPoints
                    model.CheckPoints = db.CheckPoints
                        .Where(cp => cp.DisciplineListId == DisciplineId && cp.Active == true & cp.Code != 0 & cp.Code != 4)
                        .OrderBy(cp => cp.OrderInDiscipline)
                        .ToList();

                    // Get active CheckPoint
                    if (CheckPointId == null)
                    {
                        model.ActiveCheckPoint = model.CheckPoints[0];
                        CheckPointId = model.ActiveCheckPoint.ID;
                    }
                    else
                    {
                        model.ActiveCheckPoint = db.CheckPoints.Single(cp => cp.ID == CheckPointId);
                    }

                    // Get ChipData for active CheckPoint
                    List<ChipDataView> chipDataList = GetChipDataForCheckPoint(model.ActiveCompetition.ID, model.ActiveDiscipline, model.ActiveCheckPoint.ID);

                    if (Code == "CHRES")
                    {
                        model.ChipData = (PagedList<ChipDataView>)chipDataList.ToPagedList(pageNumber, pageSize);
                    }
                }
                else if (Code == "RES")
                {
                    performances = db.Performances
                        .Where(p => p.DisciplineListId == DisciplineId && p.Active == true)
                        .OrderBy(p => p.Code)
                        .ThenBy(p => p.Rank)
                        .ToList();

                    model.Performances = (PagedList<Performances>)performances.ToPagedList(pageNumber, pageSize);
                    model.PerformancesCount = performances.Count;
                }
                else
                {
                    performances = db.Performances
                        .Where(p => p.DisciplineListId == DisciplineId)
                        .OrderByDescending(p => p.SB)
                        .ThenByDescending(p => p.PB)
                        .ThenBy(p => p.StartNumber)
                        .ThenBy(p => p.Surname)
                        .ToList();

                    if (model.ActiveDiscipline.DisciplineCode == 6)
                    {
                        performances = performances
                            .OrderBy(p => p.StartNumber)
                            .ThenBy(p => p.CountryId)
                            .ThenBy(p => p.Surname)
                            .ThenBy(p => p.FirstName)
                            .ToList();
                    }

                    model.Performances = (PagedList<Performances>)performances.ToPagedList(pageNumber, pageSize);
                    model.PerformancesCount = performances.Count;
                }
            }
            
            return View(model);
        }

        public ActionResult ChipViewerItemsPartial(int CompetitionId, int DisciplineListId, int CheckPointId)
        {
            LiveModel model = new LiveModel();
            model.ActiveDiscipline = db.DisciplineList.Single(dl => dl.ID == DisciplineListId);
            
            List<ChipDataView> chipDataList = GetChipDataForCheckPoint(CompetitionId, model.ActiveDiscipline, CheckPointId);
            model.Top3 = chipDataList.Take(1).ToList();
            if (chipDataList.Count <= 9)
            {
                model.Last = chipDataList.Skip(1).Take(8).ToList();
            }
            else
            {
                model.Last = chipDataList.Skip(chipDataList.Count - 8).Take(8).ToList();
            }
            
            ViewBag.Refreshed = string.Format("{0:00}:{1:00}:{2:00}", DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            return PartialView("ChipViewerItemsPartial", model);
        }

        public List<ChipDataView> GetChipDataForCheckPoint(int competitionId, DisciplineList discipline, int CheckPointId)
        {
            // Get ChipData for active CheckPoint
            var chipData = (
                from cd in db.ChipData.Where(cd => cd.CompetitionId == competitionId)
                join cp in db.CheckPoints on new { a = cd.PcId, b = cd.LapCount } equals new { a = cp.PcId, b = cp.LapCount }
                join dl in db.DisciplineList on new { c = (int)cp.DisciplineListId, d = cd.MeasurementId } equals new { c = dl.ID, d = (int)dl.MeasurementId }
                join c in db.Competitions on new { a = (int)dl.CompetitionId, b = cd.CompetitionId } equals new { a = c.ID, b = c.ID }
                join ct in db.ChipTags on new { a = cd.ChipTag, b = (int)cd.ChipTagsGroupId } equals new { a = ct.ChipTag, b = ct.ChipTagsGroupId }
                join p in db.Performances on new { a = ct.StartNumber, b = dl.ID } equals new { a = p.StartNumber, b = p.DisciplineListId }
                where cp.ID == CheckPointId
                orderby cd.ChipDateTime ascending
                select new
                {
                    cd.CompetitionId,
                    cd.MeasurementId,
                    cd.DataIndex,
                    cd.PcId,
                    cd.LapCount,
                    cd.ChipTag,
                    cd.ChipDateTime,

                    PerformanceId = p.ID,
                    DisciplineListId = dl.ID,

                    p.StartNumber,
                    p.Surname,
                    p.FirstName,
                    p.Birthdate,
                    p.CountryId,
                    p.Club,
                    p.SMS,

                    CheckPointName = cp.Name,
                    DisciplineListName = dl.Name
                }
                ).ToList();

            int rank = 1;
            List<ChipDataView> chipDataList = new List<ChipDataView>();
            foreach (var line in chipData)
            {
                TimeSpan ts = line.ChipDateTime.Value.TimeOfDay - discipline.StartTimeSpan;

                ChipDataView cdv = new ChipDataView(line.CompetitionId, line.MeasurementId, line.DataIndex, line.PcId, (int)line.LapCount, line.ChipTag, (DateTime)line.ChipDateTime, ts,
                    line.PerformanceId, line.DisciplineListId, (int)line.StartNumber, line.Surname, line.FirstName, (DateTime)line.Birthdate, line.CountryId, line.Club, line.SMS, rank,
                    line.CheckPointName, line.DisciplineListName, string.Empty, string.Empty);
                chipDataList.Add(cdv);

                rank += 1;
            }

            return chipDataList;
        }

    }
}
